#pragma once

#include "SkinDef.h"
#include "SkinableGUIImage.h"

#include <map>

// CSkinableGUIWnd
namespace SkinableGUI
{
	class CSkinableGUIWnd : public CWnd
	{
		DECLARE_DYNAMIC(CSkinableGUIWnd)

		struct ChildWindow
		{
			CWnd * pWnd;
			SkinControl * pSkinControl;
		};

		class CChildWindowList :public std::vector<ChildWindow>
		{
		};

		class CChildWindowMap :public std::map<UINT, ChildWindow>
		{
		};

	public:
		CSkinableGUIWnd(const CString & pSkinFile);
		CSkinableGUIWnd(SkinControl * pSkinControl);
		virtual ~CSkinableGUIWnd();

	protected:
		DECLARE_MESSAGE_MAP()
	public:
		virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
		virtual BOOL CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, LPVOID lpParam = NULL);
	protected:
		virtual void CalcWindowRect(LPRECT lpClientRect, UINT nAdjustType = adjustBorder);
		virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
	public:
		virtual BOOL DestroyWindow();
		virtual BOOL OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pLResult);
	protected:
		virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
		virtual void PostNcDestroy();
		virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	public:
		afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
		afx_msg void OnDestroy();
		afx_msg BOOL OnEraseBkgnd(CDC* pDC);
		afx_msg void OnPaint();
		afx_msg void OnSize(UINT nType, int cx, int cy);
		
	protected:
		CString m_strSkinXmlPath;

		SkinControl * m_pSkinControl;
		BOOL m_bDestroySkinControl;

		CSkinableGUIImage m_BackgroundImage;

		COLORREF m_BackgroundColor;

		CSkinableGUIImageList m_Pictures;

		CChildWindowList m_ChildrenWindows;
		CChildWindowMap m_ChildrenWindowsMap;

		void SkinRectToClient(CRect & rc);

		CBitmap * m_pBackgroundImage;

		int m_nBackgroundWidth;
		int m_nBackgroundHeight;

		CBitmap * m_pSavedBackgroundBmp;

		void DestroyBackgroundPainter();
		void PrepareBackgroundPainter(CDC * pDC, const CRect & rcBackground);
		BOOL CreateSkinFont(CFont & font, COLORREF & txtColor, COLORREF & bkColor);
		void DoWndPaint(CDC * pDC);
		virtual void DoRefreshWindow(const RECT * lpRect = NULL, BOOL bErase = TRUE);
	public:
		afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnSetFocus(CWnd* pOldWnd);
		afx_msg UINT OnGetDlgCode();

		CWnd * GetChildWnd(UINT nID);

		virtual void Invalidate(BOOL bErase = TRUE);
		virtual void InvalidateRect(const RECT * lpRect, BOOL bErase = TRUE);
	};

	enum 
	{
		WM_SKINABLE_WINDOW_MSG_BASE = WM_USER + 6000
	};
}

